package com.dsw.demo.websocket.controller;


import com.alibaba.fastjson.JSONObject;
import com.dsw.demo.websocket.utils.SpringUtil;
import com.dsw.demo.websocket.utils.StringUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.Collection;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;


@ServerEndpoint(value = "/websocket/{username}")
@Component
public class WebSocketController {

    private static final Logger logger = LoggerFactory.getLogger(WebSocketController.class);


    public static final Map<String, Session> sessionMap = new ConcurrentHashMap();

    private static int onlineCount = 0;
    private Session session;
    private String username;


    @OnOpen
    public void onOpen(@PathParam("username") String username, Session session) {


        this.username = username;
        this.session = session;

        addOnlineCount();
        sessionMap.put(username, session);
        logger.info(this.username + " 已连接");
    }

    @OnClose
    public void onClose() {
        sessionMap.remove(username);
        logger.info(this.username + " 已关闭");
        subOnlineCount();
    }

    @OnMessage
    public void onMessage(String message) throws IOException {
        logger.info("收到消息：" + message);
        JSONObject jsonTo = JSONObject.parseObject(message);
        Object pong = jsonTo.get("pong");
        if (pong != null) {//pong数据不做处理
            return;
        }
        if (!jsonTo.get("to").equals("All")) {
            sendMessageTo(jsonTo.get("msg").toString(), jsonTo.get("to").toString(), message);
        } else {
            sendMessageAll(jsonTo.get("msg").toString());
        }
    }

    @OnError
    public void onError(Session session, Throwable error) {
        error.printStackTrace();
    }

    public void sendMessageTo(String message, String toUser, String jsonMessage) throws IOException {

        boolean sendFlag = false;
        Set<Map.Entry<String, Session>> entries = sessionMap.entrySet();
        for (Map.Entry<String, Session> entry : entries) {
            String key = entry.getKey();
            if (StringUtil.isNotBlank(key) && key.equals(toUser)) {
                Session session = entry.getValue();
                if (session != null) {
                    JSONObject msgData = new JSONObject();
                    msgData.put("msg", message);
                    session.getAsyncRemote().sendText(msgData.toString());
                    sendFlag = true;
                }
            }

        }

        if (!sendFlag) {
            logger.info("收到用户消息，目标接受者不在本服务器，发送redis广播");
            StringRedisTemplate stringRedisTemplate = SpringUtil.getBean(StringRedisTemplate.class);
            stringRedisTemplate.convertAndSend("chat", jsonMessage);

        }
    }

    public void sendMessageAll(String message) {
        Collection<Session> values = sessionMap.values();
        for (Session session : values) {
            JSONObject msgData = new JSONObject();
            msgData.put("msg", message);
            session.getAsyncRemote().sendText(msgData.toString());
        }

    }


    public static synchronized int getOnlineCount() {
        return onlineCount;
    }

    public static synchronized void addOnlineCount() {
        onlineCount++;
    }

    public static synchronized void subOnlineCount() {
        onlineCount--;
    }

    public static synchronized Map<String, Session> getClients() {
        return sessionMap;
    }


}
